package com.ezlcp.user.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ezlcp.commons.base.db.BaseService;
import com.ezlcp.commons.base.entity.IUser;
import com.ezlcp.commons.base.entity.JsonResult;
import com.ezlcp.commons.constant.Constants;
import com.ezlcp.commons.constant.StatusEnum;
import com.ezlcp.commons.tool.StringUtils;
import com.ezlcp.commons.utils.ContextUtil;
import com.ezlcp.user.entity.Menu;
import com.ezlcp.user.entity.TenantMenu;
import com.ezlcp.user.enums.MenuTypeEnum;
import com.ezlcp.user.service.MenuServiceImpl;
import com.ezlcp.user.service.TenantMenuServiceImpl;
import com.ezlcp.user.web.BaseController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.io.Console;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/ezlcp/user/menu")
@Tag(name = "系统菜单表")
public class MenuController extends BaseController<Menu> {
    @Autowired
    MenuServiceImpl menuService;
    @Resource
    TenantMenuServiceImpl tenantMenuService;

    @Operation(summary = "根据前端的路由取对应的菜单名")
    @GetMapping("getMenuName")
    public String getMenuName(@Parameter(description = "前端的路由") @RequestParam(value = "path") String path) {
        return menuService.getMenuName(path);
    }

    @Operation(summary = "a.获取当前用户已授权的菜单")
    @PostMapping("/getUserMenus")
    public JsonResult getUserMenus() {
        IUser user = ContextUtil.getCurrentUser();
        if (user == null) {
            return JsonResult.Fail("common.firstLogin");
        }
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setShow(false);
        String userId = user.getUserId();
        String tenantId = user.getTenantId();
        List<TenantMenu> menus = null;
        if (user.isPlatformUser()) {
            //超管
            if (user.isAdmin()) {
                menus = menuService.getPlatformMenus();
            } else {//平台用户（管理员）
                menus = menuService.getPlatUserMenus(userId);
            }
        } else {
            //公司管理员
            if (user.isAdmin()) {
                menus = menuService.getTenantAllMenus(tenantId);
            } else {//普通用户
                menus = menuService.getCommonUserMenus(userId, tenantId);
            }
        }
        if (menus != null) {
            for (var menu : menus) {
                menu.setSourceId(menu.getMenuId());
                menu.setMenuId(menu.getPkId());
            }
            result.setData(menus);
        }
        return result;
    }

    @Operation(summary = "b.获取普通用户某个页面中的权限（按钮等）", description = "system或company拥有页面全部权限，可跳过调用本接口")
    @PostMapping("/getUserPageAuth")
    public JsonResult getUserPageAuth(@Parameter(description = "菜单Id")
                                      @RequestParam(value = "menuId") String menuId) {
        IUser user = ContextUtil.getCurrentUser();
        if (user == null) {
            return JsonResult.Fail("common.firstLogin");
        }
        if (StringUtils.isEmpty(menuId)) {
            return JsonResult.Fail("common.paramError");
        }
        var menu = tenantMenuService.getById(menuId);
        if (menu == null) {
            return JsonResult.Fail("common.paramError");
        }
        JsonResult result = JsonResult.Success("common.handleSuccess");
        Object data = menuService.getUserPageAuth(user.getUserId(), menu);
        result.setData(data);
        result.setShow(false);
        return result;
    }

    @Operation(summary = "i.获取当前用户全部页面中的控件权限（按钮等）", description = "system或company用户也可以调用，返回全部权限")
    @PostMapping("/getUserAllPageAuth")
    public JsonResult getUserAllPageAuth() {
        IUser user = ContextUtil.getCurrentUser();
        if (user == null) {
            return JsonResult.Fail("menu.firstLogin");
        }
        JsonResult result = JsonResult.Success("menu.success");
        Object data = menuService.getCurUserPageAuth();
        result.setData(data);
        return result;
    }

    @Operation(summary = "c.获取当前用户所有可授权菜单")
    @PostMapping("/getAllMenus")
    public JsonResult getAllMenus() {
        IUser user = ContextUtil.getCurrentUser();
        if (user == null) {
            return JsonResult.Fail("common.firstLogin");
        }
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setShow(false);
        //管理账号
        if (user.isPlatformUser()) {
            result.setData(menuService.getPlatformMenus());
        } else {
            result.setData(menuService.getTenantAllMenus(user.getTenantId()));
        }
        return result;
    }

    @Operation(summary = "d.获取菜单页面元素（按钮等权限）")
    @PostMapping("/getPageElements")
    public JsonResult getPageElements(@Parameter(description = "菜单Id,不传则查询全部元素")
                                      @RequestParam(value = "menuId", required = false) String menuId) {
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setShow(false);
        result.setData(menuService.getElements(menuId));
        return result;
    }

    @Operation(summary = "h.获取用户组的授权信息")
    @PostMapping("/getGroupAuthInfo")
    public JsonResult getGroupAuthInfo(@Parameter(description = "用户组Id")
                                       @RequestParam(value = "groupId") String groupId) {
        if (StringUtils.isEmpty(groupId)) {
            return JsonResult.Fail("common.paramError");
        }
        JsonResult result = menuService.getGroupAuthInfo(groupId);
        if (result.isSuccess()) {
            logService.saveSystemLog(getComment(), "getGroupAuthInfo", groupId, null);
        }
        return result;
    }

    @Operation(summary = "f.修改用户组的菜单授权", description = "<font color='red'><b>会先删除该用户组的旧菜单授权，再插入新授权</b></font>" +
            "<br>请求参数示例格式：{\n" +
            "<br>    \"groupId\": \"1\",\n" +
            "<br>    \"auth\": [\n" +
            "<br>        {\n" +
            "<br>            \"menuId\": 111,\n" +
            "<br>            \"hasElement\": \"1\",\n" +
            "<br>            \"elements\": [{\"elementKey\":\"add\",\"elementName\":\"新增\",\"type\": \"button\"}" +
            ",{\"elementKey\":\"edit\",\"elementName\":\"編輯\",\"type\": \"button\"}]\n" +
            "<br>        },\n" +
            "<br>        {\n" +
            "<br>            \"menuId\": 131,\n" +
            "<br>            \"hasElement\": 1,\n" +
            "<br>            \"elements\": []\n" +
            "<br>        }    ]\n" +
            "<br>}" +
            "<br>groupId为用户组ID，menuId为菜单ID一个菜单最多只能有一条记录，hasElement值为（0表求该菜单下面不需要控制按钮权限，否则为1），" +
            "<br>elements为已选择授权的元素数据组[{元素Key,元素名，类型}]")
    @PostMapping("/editGroupMenus")
    public JsonResult editGroupMenus(@RequestBody JSONObject data) {
        String groupId = data.getString("groupId");
        JSONArray auth = data.getJSONArray("auth");
        if (StringUtils.isEmpty(groupId) || auth == null) {
            return JsonResult.Fail("common.paramError");
        }
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setShow(false);
        menuService.editGroupMenus(groupId, auth);
        logService.saveSystemLog(getComment(), "Group authorization", groupId, JSON.toJSONString(auth));
        return result;
    }

    @Override
    public JsonResult<Menu> get(@RequestParam(value = "pkId") String pkId) {
        IUser user = ContextUtil.getCurrentUser();
        if (user == null || StringUtils.isEmpty(pkId)) {
            return JsonResult.Fail("common.paramError");
        }
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setShow(false);
        result.setData(tenantMenuService.getById(pkId));
        return result;
    }

    @Operation(summary = "可选择的父节点")
    @PostMapping("/selectParent")
    public JsonResult selectParent(@Parameter(description = "当前菜单主键") @RequestParam(value = "pkId", required = false) String pkId) {
        JsonResult result = JsonResult.Success("common.handleSuccess");
        result.setData(menuService.selectParent(pkId));
        return result;
    }

    @Override
    public JsonResult save(Menu entity, BindingResult validResult) throws Exception {
        return JsonResult.Fail("common.apiClose");
    }

    @Operation(summary = "保存修改菜单")
    @PostMapping("/saveMenu")
    public JsonResult saveMenu(@Parameter(description = "菜单") @RequestBody TenantMenu entity) throws Exception {
        String tenantId = ContextUtil.getCurrentTenantId();

        //校验数据
        if(StringUtils.isEmpty(entity.getUrl())|| StringUtils.isEmpty(entity.getMenuName())
                || StringUtils.isEmpty(entity.getHkName()) || StringUtils.isEmpty(entity.getEnName())
                || entity.getMenuType()==null ||  entity.getFrontType()==null){
            return JsonResult.Fail("common.paramError");
        }
        String component=entity.getComponent();
        String parentId = entity.getParentId();
        String newUrl=entity.getUrl().replace("/","");
        if(entity.getMenuType()==MenuTypeEnum.Directory.getValue()){
            entity.setComponent("#");
            if(!entity.getUrl().startsWith("/") && StringUtils.isEmpty(parentId)){
                entity.setUrl("/" + entity.getUrl());
            }else {
                entity.setUrl(newUrl);
            }
        }else {
            entity.setUrl(newUrl);
        }
        if(StringUtils.isEmpty(component)){
            return JsonResult.Fail("common.paramError");
        }
        if(!tenantMenuService.isUrlUnique(entity.getUrl(),entity.getPkId())){
            return JsonResult.Fail("menu.uniqueUrl");
        }
        //校验父菜单
        if (StringUtils.isEmpty(parentId)) {
            entity.setParentId(null);
            entity.setPageLevel(Constants.SHORT1);
        } else {
            var parent = tenantMenuService.getById(parentId);
            if (parent == null || parent.getMenuType()!= MenuTypeEnum.Directory.getValue()) {
                return JsonResult.Fail("common.paramError");
            }
            int pageLevel=parent.getPageLevel() +1;
            entity.setPageLevel((short)pageLevel);
        }
        //目录菜单
        entity.setTenantId(tenantId);
        //新增
        if (StringUtils.isEmpty(entity.getPkId())) {
            entity.setStatus((short)StatusEnum.enable.getValue());
            entity.setIsCustom((short)1);
            entity.setHidden((short)0);
            entity.setIsDirect((short)0);
            entity.setSeq(1);
            tenantMenuService.insert(entity);
        } else { //修改
            entity.setSeq(entity.getSeq() + 1);
            tenantMenuService.updateById(entity);
        }
        logService.saveSystemLog(getComment(), "Save TenantMenu", entity.getPkId(), JSON.toJSONString(entity));
        return JsonResult.getSuccessResult("common.handleSuccess");
    }

    @Operation(summary = "删除租户菜单")
    @Override
    public JsonResult del(@Parameter(description = "租户菜单ID") @RequestParam(value = "pkId") String pkId) {
        String tenantId = ContextUtil.getCurrentTenantId();
        var entity = tenantMenuService.getById(pkId);
        if (entity == null) {
            return JsonResult.Fail("common.paramError");
        }
        String srcTenantId = entity.getTenantId();
        if (StringUtils.compare(tenantId, srcTenantId) != 0) {
            return JsonResult.Fail("common.paramError");
        }
        entity.setSeq(entity.getSeq() + 1);
        entity.setStatus((short) StatusEnum.deleted.getValue());
        tenantMenuService.updateById(entity);
        logService.saveSystemLog(getComment(), "Delete TenantMenu", entity.getPkId(), JSON.toJSONString(entity));
        return JsonResult.getSuccessResult("common.handleSuccess");
    }

    @Override
    public BaseService getBaseService() {
        return menuService;
    }

    @Override
    public String getComment() {
        return "菜单管理";
    }
}